package gw.com.android.ui.bulletin;

import android.app.Dialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.gwtsz.android.rxbus.RxBus;
import com.gwtsz.gts2.hx.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import gw.com.android.app.AppContances;
import gw.com.android.app.AppMain;
import gw.com.android.app.GTConfig;
import gw.com.android.greendao.NotifyDataHelper;
import gw.com.android.presenter.http.HttpCallback;
import gw.com.android.ui.BaseActivity;
import gw.com.android.ui.record.RecordActivity;
import gw.com.android.ui.system.PushSettingActivity;
import gw.com.android.utils.AppTest;
import gw.com.android.utils.ENV;
import gw.com.android.utils.NotificationUtil;
import gw.com.android.utils.PackStatis;
import gw.com.android.utils.ThreadPool;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import www.com.library.dialog.ToastPopWindow;
import www.com.library.view.BtnClickListener;
import www.com.library.view.XRecyclerView;

/**
 * @author jett
 * @since 2018-07-26.
 */
public class NotifyCentreActivity extends BaseActivity {

    @BindView(R.id.notice_centre_listview)
    XRecyclerView rvList;
    @BindView(R.id.notice_centre_setting)
    TextView tvSetting;
    @BindView(R.id.notice_centre_setting_desc)
    TextView tvSettingDesc;

    private boolean refreshOpenSys = false;
    private boolean showOpenSys = false;
    private NotifyCentreAdapter mAdapter;
    private NotifyEmptyAdapter emptyAdapter;
    private HashMap<Integer, String> categoryArr;

    long[] mHints = new long[10];

    @Override
    protected int getLayoutView() {
        return R.layout.activity_notify_centre;
    }

    @Override
    protected void initLayoutView() {
        mTitleBar.mTitleView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.arraycopy(mHints, 1, mHints, 0, mHints.length - 1);
                mHints[mHints.length - 1] = System.currentTimeMillis();
                if (System.currentTimeMillis() - mHints[0] <= 2000) {
                    mHints = new long[10];
                    if (!ENV.isRelease()) {
                        startActivity(new Intent(getApplicationContext(), RecordActivity.class));
                    }
                    new ToastPopWindow(AppMain.getApp(), "(^_^)").show();
                }
            }
        });
        mTitleBar.mTitleView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (!ENV.isRelease()) {
                    new AppTest().record(NotifyCentreActivity.this);
                }
                return false;
            }
        });

        mTitleBar.setAppTitle(R.string.push_category_title);
        mTitleBar.setBtnClickListener(new BtnClickListener() {
            @Override
            public void onBtnClick(int viewID) {
                if (viewID == R.id.title_left_icon) {
                    finish();
                } else if (viewID == R.id.title_right_text) {
                    PackStatis.getToService("clickRead", "Me", null, null);
                    showDialog();
                }
            }
        });
        boolean openSysShowed = GTConfig.instance().getBooleanValue("notify_open_sys_showed", false);
        showOpenSys = !openSysShowed && !NotificationUtil.isNotificationEnabled(getApplicationContext());
    }

    @Override
    protected void initViewData() {
        rvList.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        emptyAdapter = new NotifyEmptyAdapter(this, showOpenSys);
        rvList.setAdapter(emptyAdapter);
        rvList.setNoMore(false);
        rvList.setLoadingMoreEnabled(false);
        rvList.refreshComplete();
        rvList.setLoadingListener(new XRecyclerView.LoadingListener() {
            @Override
            public void onRefresh() {
                onRefreshing();
            }

            @Override
            public void onLoadMore() {
            }
        });

        NotifyRequest notifyRequest = new NotifyRequest();
        categoryArr = notifyRequest.fetchCategory();

        if (categoryArr != null && categoryArr.size() > 0) {
            loadCategory();
            notifyRequest.getCategory(null);
        } else {
            notifyRequest.getCategory(new HttpCallback<HashMap<Integer, String>>() {
                @Override
                public void onSuccess(HashMap<Integer, String> result) {
                    if (result != null && result.size() > 0) {
                        categoryArr = result;
                        loadCategory();
                    }
                }

                @Override
                public void onFailure(Exception e) {
                    new ToastPopWindow(getApplicationContext(), "网络异常，请检查您的网络设置").show();
                }
            });
        }
    }

    private void loadCategory() {
        refreshSettingView();
        mAdapter = new NotifyCentreAdapter(this, showOpenSys);
        List<NotifyCategoryData> data = initCategoryData(categoryArr);
        mAdapter.setData(data);
        rvList.setAdapter(mAdapter);
        emptyAdapter = null;
        loadNotify();
    }

    private void loadNotify() {
        new LocalTask().execute(true);
        new NotifyRequest().getNoticeList(GTConfig.instance().mCurName, null);
    }

    private List<NotifyCategoryData> initCategoryData(HashMap<Integer, String> arr) {
        if (arr == null || arr.size() <= 0) {
            return null;
        }
        List<NotifyCategoryData> list = new ArrayList<>();
        for (Map.Entry<Integer, String> me : arr.entrySet()) {
            int key = me.getKey();
            String value = me.getValue();
            list.add(new NotifyCategoryData(key, value));
        }
        Collections.sort(list, new Comparator<NotifyCategoryData>() {
            @Override
            public int compare(NotifyCategoryData o1, NotifyCategoryData o2) {
                if (o2 == null || o2.notice == null) {
                    return 1;
                }
                if (o1 == null || o1.notice == null) {
                    return -1;
                }
                return (int) (o1.notice.ctime - o2.notice.ctime);
            }
        });
        sortByCtime(list);
        return list;
    }

    private void onRefreshing() {
        if (categoryArr == null || categoryArr.size() <= 0) {
            rvList.refreshComplete();
            return;
        }
        new NotifyRequest().getNoticeList(GTConfig.instance().mCurName, new HttpCallback<List<NotifyData>>() {
            @Override
            public void onSuccess(List<NotifyData> result) {
                rvList.refreshComplete();
            }

            @Override
            public void onFailure(Exception e) {
                rvList.refreshComplete();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (refreshOpenSys) {
            refreshOpenSys = false;
            boolean openSysShowed = GTConfig.instance().getBooleanValue("notify_open_sys_showed", false);
            showOpenSys = !openSysShowed && !NotificationUtil.isNotificationEnabled(getApplicationContext());
            refreshOpenSysView();
            refreshSettingView();
        }
    }

    @Override
    public void registerRxBus() {
        Disposable noticeRegister = RxBus.getInstance().register("notification_data_update", Boolean.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(@io.reactivex.annotations.NonNull Boolean isConnection) throws Exception {
                        loadLocalNotify();
                    }
                });
        bindSubscription(noticeRegister);
    }

    private void loadLocalNotify() {
        if (categoryArr == null || categoryArr.size() <= 0) {
            return;
        }
        new LocalTask().execute();
    }

    private void showDialog() {
        long dialogCount = GTConfig.instance().getLongValue("notify_one_key_dialog_count", 0);
        if (dialogCount >= 3) {
            setAllNoticeReaded();
            return;
        }
        dialogCount += 1;
        GTConfig.instance().setLongValue("notify_one_key_dialog_count", dialogCount);

        final Dialog dialog = new Dialog(this, R.style.dialog_loading_bar_no_frame);
        View dialogView = View.inflate(this, R.layout.dialog_one_key_read, null);
        dialogView.findViewById(R.id.action_btn_neg).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialogView.findViewById(R.id.action_btn_pos).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                setAllNoticeReaded();
            }
        });
        dialog.setContentView(dialogView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        dialog.setCanceledOnTouchOutside(true);
        dialog.setCancelable(true);
        dialog.show();
    }

    private void setAllNoticeReaded() {
        ThreadPool.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                NotifyDataHelper.setAllNoticeReaded();
                NotifyDataHelper.notifyChange();
            }
        });
    }

    private class LocalTask extends AsyncTask<Boolean, Void, List<NotifyCategoryData>> {

        @Override
        protected List<NotifyCategoryData> doInBackground(Boolean... params) {
            if (params != null && params.length > 0 && params[0]) {
                NotifyDataHelper.deleteExpireData();
            }
            if (categoryArr == null || categoryArr.size() <= 0) {
                return null;
            }
            List<NotifyCategoryData> list = new ArrayList<>();
            for (Map.Entry<Integer, String> me : categoryArr.entrySet()) {
                int typeId = me.getKey();
                String name = me.getValue();
                list.add(loadCategoryDataFromDB(typeId, name));
            }
            sortByCtime(list);
            return list;
        }

        @Override
        protected void onPostExecute(List<NotifyCategoryData> result) {
            refreshUi(result);
        }

    }

    private NotifyCategoryData loadCategoryDataFromDB(int typeId, String name) {
        NotifyCategoryData data = new NotifyCategoryData(typeId, name);
        data.unreadCount = NotifyDataHelper.getUnreadCount(typeId);
        data.notice = NotifyDataHelper.getLastNotice(typeId);
        return data;
    }

    private void sortByCtime(List<NotifyCategoryData> list) {
        Collections.sort(list, new Comparator<NotifyCategoryData>() {
            @Override
            public int compare(NotifyCategoryData o1, NotifyCategoryData o2) {
                if (o1 == null || o1.notice == null) {
                    return 1;
                }
                if (o2 == null || o2.notice == null) {
                    return -1;
                }
                return (int) (o2.notice.ctime - o1.notice.ctime);
            }
        });
    }

    private void refreshUi(List<NotifyCategoryData> result) {
        if (result != null && !result.isEmpty()) {
            int unReadCount = 0;
            for (NotifyCategoryData categoryData : result) {
                unReadCount += categoryData.unreadCount;
            }
            if (unReadCount > 0) {
                mTitleBar.setRightText(R.string.push_one_key_read);
            } else {
                mTitleBar.setRightText("");
            }
        }
        if (mAdapter != null) {
            mAdapter.setData(result);
        }
    }

    private void refreshOpenSysView() {
        if (mAdapter != null) {
            mAdapter.setShowOpenSys(showOpenSys);
            mAdapter.notifyDataSetChanged();
        }
        if (emptyAdapter != null) {
            emptyAdapter.setShowOpenSys(showOpenSys);
            emptyAdapter.notifyDataSetChanged();
        }
    }

    private void refreshSettingView() {
        if (GTConfig.instance().getAccountType() != GTConfig.ACC_TYPE_GUEST && NotificationUtil.isNotificationEnabled(getApplicationContext())) {
            boolean showed = GTConfig.instance().getBooleanValue("notify_to_setting", false);
            if (showed) {
                return;
            }
            GTConfig.instance().setBooleanValue("notify_to_setting", true);
            tvSettingDesc.setVisibility(View.VISIBLE);
            tvSetting.setVisibility(View.VISIBLE);
            tvSetting.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    PackStatis.getToService("clickSet", "Me", null, null);
                    startActivity(new Intent(getApplicationContext(), PushSettingActivity.class));
                    tvSettingDesc.setVisibility(View.GONE);
                    tvSetting.setVisibility(View.GONE);
                }
            });
        } else {
            tvSettingDesc.setVisibility(View.GONE);
            tvSetting.setVisibility(View.GONE);
        }
    }

    @Override
    public void startActivityForResult(Intent intent, int requestCode) {
        if (requestCode == AppContances.REQUEST_SYSTEM_PUSH_CODE) {
            // 用此方法打开系统通知时，onActivityResult 会直接收到 cancel 的 resuleCode ，所以，换种实现方式
            refreshOpenSys = true;
        }
        super.startActivityForResult(intent, requestCode);
    }

}
